package com.packenius.library.xspdf;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Christian Packenius, 2013.
 */
abstract class XST1StdFont {
  abstract String getFontName();

  /**
   * Maps a glyph fontType to the width of this glyph.
   */
  final Map<Character, Double> glyphWidths = new HashMap<Character, Double>();

  /**
   * Maps a glyph fontType pair ("glyphname1-glyphname2") to the kerning
   * distance.
   */
  final Map<String, Double> glyphPairKerning = new HashMap<String, Double>();

  /**
   * Maps an Utf-8 (Unicode?) code (0..65535) to the byte in the standard font
   * encoding.
   */
  public final Map<Character, Character> standardEncodingCodeFromUnicodeCharacter = new HashMap<Character, Character>();

  double getAscender() {
    // Please override!
    return 1.0;
  }

  double getDescender() {
    // Please override!
    return 0.0;
  }

  XST1StdFont() {
    addCharMetrics();
    addKernPairs();
  }

  abstract void addCharMetrics();

  void addKernPairs() {
    // Overwrite!
  }

  double getKerning(String glyph1, String glyph2) {
    Double kerning = glyphPairKerning.get(glyph1 + "-" + glyph2);
    if (kerning == null) {
      return 0;
    }
    return kerning;
  }

  /**
   * If a character is part of this font but not part of the standard font
   * encoding, get another encoding here.
   * 
   * @param character
   * @return
   */
  XSAlternativeFontEncoding getAlternativeFontEncoding(char character) {
    String fontName = getFontName();
    // System.out.println("XST1StdFont.name := " + fontName);
    if (fontName.equals("Symbol")) {
      if (character == '\uF8FF') {
        return new XST1AltFontEncoding4();
      }
      throw new XSPdfException("Symbol with character 0x" + Integer.toHexString(character) + " is standard encoded!");
    }
    if (fontName.equals("ZapfDingbats")) {
      throw new XSPdfException(fontName + " has no alternative font encoding!");
    }
    if (standardEncodingCodeFromUnicodeCharacter.get(character) != null) {
      throw new XSPdfException(fontName + " with character 0x" + Integer.toHexString(character)
          + " is standard encoded!");
    }
    if (XST1AltFontEncoding1.altFontEncoding1.containsKey(character)) {
      return new XST1AltFontEncoding1();
    }
    if (XST1AltFontEncoding2.altFontEncoding2.containsKey(character)) {
      return new XST1AltFontEncoding2();
    }
    if (XST1AltFontEncoding3.altFontEncoding3.containsKey(character)) {
      return new XST1AltFontEncoding3();
    }
    throw new XSPdfException("Glyph 0x" + Integer.toHexString(character) + " does not exist in font " + fontName);
  }
}
